﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Instances.Contracts;
using Umbrella.Net.Contracts;
using Umbrella.Whs;
using ErrorInfo = Instances.Contracts.ErrorInfo;
using LatestVersionQuery = Instances.Contracts.LatestVersionQuery;
using ReleaseInfo = Instances.Contracts.ReleaseInfo;

namespace Umbrella.Net.Web.Services
{
    partial class UmbrellaService
    {

        public UmbrellaReleaseInfo GetLatestVersion(LatestVersionQuery query)
        {
            if (query == null)
                throw new ArgumentNullException("query");

            try
            {
                using (var i = new InstancesServiceClientFactory())
                {
                    // query version
                    query.ProductId = UmbrellaVersion.ProductId;

                    var ri = i.CreateChannel().GetLatestVersion(query);

                    // no version found?
                    if (ri.ReleaseId <= 0)
                        return new UmbrellaReleaseInfo(ri);

                    // lookup sharepoint release
                    var spr = (
                        from r in _entities.Releases
                        where r.ReleaseId == ri.ReleaseId
                        select r
                        ).FirstOrDefault();

                    if (spr == null)
                    {
                        throw new Exception("No extended release information found: " + ri.ReleaseId);
                    }

                    if (!spr.SharePointVersionReference.IsLoaded)
                        spr.SharePointVersionReference.Load();

                    // finalize
                    return new UmbrellaReleaseInfo(ri)
                    {
                        SharePointBuildId = spr.SharePointVersion.BuildNumber,
                        SharePointVersionString = spr.SharePointVersion.VersionString
                    };
                }
            }
            catch (Exception x)
            {
                _log.Error("Failed to query latest version", x);

                throw;
            }
        }

        public void ReportError(ErrorInfo error)
        {
            try
            {
                throw new NotSupportedException("Please upgrade Codename 'Umbrella' version!");
            }
            catch (Exception x)
            {
                _log.Error("Failed to report error", x);

                throw;
            }
        }

        public IEnumerable<SharePointVersionInfo> GetSharePointVersions()
        {
            try
            {
                return (
                    from e in _entities.SharePointVersions
                    select e
                    ).ToArray().Select((s) => s.ToContract());
            }
            catch (Exception ex)
            {
                _log.Error("Failed to load SharePoint versions", ex);

                throw;
            }
        }

        public IEnumerable<SharePointLanguage> GetSharePointLanguages()
        {
            try
            {
                return (
                    from e in _entities.SharePointLanguages
                    select e
                    ).ToArray().Select((s) => s.ToContract());
            }
            catch (Exception ex)
            {
                _log.Error("Failed to load SharePoint languages", ex);

                throw;
            }
        }

        public IEnumerable<SharePointInstallationFile> GetSharePointInstallationFiles(int buildNumber)
        {
            try
            {
                var bn = GetBestMatchingBuildNumber(buildNumber);

                return (
                    from e in _entities.SharePointInstallationFiles
                    where e.BuildNumber == bn
                    select e
                    ).ToArray().Select((s) => s.ToContract());
            }
            catch (Exception ex)
            {
                _log.Error("Failed to load SharePoint installation files for " + buildNumber, ex);

                throw;
            }
        }

        public int GetBestMatchingBuildNumber(int buildNumber)
        {
            try
            {
                return (
                    from v in _entities.SharePointVersions
                    where v.BuildNumber <= buildNumber
                    orderby v.BuildNumber descending
                    select v.BuildNumber
                    ).FirstOrDefault();
            }
            catch (Exception ex)
            {
                _log.Error("Failed to find best matching SharePoint build for " + buildNumber, ex);

                throw;
            }
        }
    }
}